package cn.backflow.utils;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

public class Cartesian {

    public static void main(String[] args) {

        String bet = "32|3|3|3|3|3|3|3|3|3|3|3|3|3";
        String[] bets = bet.split("\\|", -1);

        /*
        String[][] arrays = Arrays.stream(bets).map(b -> b.split("")).collect(Collectors.toList()).toArray(new String[][]{});

        for (int[] indices : new IndexIterator(arrays)) {
            // System.out.println(Arrays.toString(indices));
            for (int i = 0; i < arrays.length; i++) {
                System.out.print(arrays[i][indices[i]] + " ");
            }
            System.out.println();
        }*/

        int[][] combinations = combinations(new int[][]{{2, 3}, {4, 5}, {6, 7, 8}, {9}});

        for (int[] combination : combinations) {
            System.out.println(Arrays.toString(combination));
        }
        /*

        List<String[]> list = new ArrayList<String[]>() {{
            add(new String[]{"1", "2", "3"});
            add(new String[]{"4", "5"});
            add(new String[]{"6", "7", "8"});
            add(new String[]{"9"});
        }};

        for (String[] combination : combinations(list)) {
            System.out.println(Arrays.toString(combination));
        }
        */
    }

    public static int[][] combinations(int[][] arrays) {
        int len = arrays.length;
        int solutions = 1, i = 0;
        for (i = 0; i < len; solutions *= arrays[i].length, i++) ;
        int[][] combinations = new int[solutions][];
        for (i = 0; i < solutions; i++) {
            int[] combination = new int[len];
            int j = 1, k = 0;
            for (int[] arr : arrays) {
                combination[k++] = arr[(i / j) % arr.length];
                j *= arr.length;
            }
            combinations[i] = combination;
        }
        return combinations;
    }

    public static String[][] combinations(List<String[]> strings) {
        int size = strings.size();
        int solutions = 1;
        for (String[] arr : strings) {
            solutions *= arr.length;
        }
        String[][] combinations = new String[solutions][];
        for (int i = 0; i < solutions; i++) {
            String[] combination = new String[size];
            int j = 1, k = 0;
            for (String[] arr : strings) {
                combination[k++] = arr[(i / j) % arr.length];
                j *= arr.length;
            }
            combinations[i] = combination;
        }

        return combinations;
    }

    static Iterator<int[]> indexIterator (Object[][] objects) {
        return new IndexIterator(objects);
    }

    static class IndexIterator implements Iterable<int[]>, Iterator<int[]> {

        private final int[] lengths;
        private final int[] indices;
        private boolean next = true;

        IndexIterator(Object[][] objects) {
            int length = objects.length;
            lengths = new int[length];
            indices = new int[length];
            for (int i = 0; i < length; i++) {
                lengths[i] = objects[i].length;
            }
        }

        public boolean hasNext() {
            return next;
        }

        public int[] next() {
            int[] result = Arrays.copyOf(indices, indices.length);
            for (int i = indices.length - 1; i >= 0; i--) {
                if (indices[i] == lengths[i] - 1) {
                    indices[i] = 0;
                    if (i == 0) {
                        next = false;
                    }
                } else {
                    indices[i]++;
                    break;
                }
            }
            return result;
        }

        public Iterator<int[]> iterator() {
            return this;
        }

        public void remove() {
            throw new UnsupportedOperationException();
        }
    }
}
